import { Component, Host, QueryList, ViewChildren, ContentChildren, Input, Output, EventEmitter } from "@angular/core";
import { AppComponent } from "../../../../../app.component";
import { ReportingService, TargetType } from "../../../reporting.service";
import { ActivatedRoute } from "@angular/router";
import { TemplateCriteriaModel } from "../../../models/templateCriteria.model";
import { BaseCriteriaTemplateComponent } from "./types/baseType.component";
import { CriteriaComponent } from "../criteria.component";
import { ICriteriaTemplate, TemplateType } from "./models/criteriaTemplate.interface";
import { SliderModel, HistogramModel, BaseTemplateOutput, UnscreenableModel, MultiSelectModel, InvolvementModel } from "./models/save/criteriaTemplateOutput.models";
import { ICriteriaOutput } from "./models/save/criteriaOutput.interface";
import { SliderOutput, HistogramOutput, MultiselectOutput, InvolvementOutput } from "./models/save/criteriaOutput.model";
import { Subscription } from "rxjs";

@Component({
    templateUrl: 'templateCriteria.component.html',
    styleUrls: ['./templateCriteria.component.scss']
})
export class TemplateCriteriaComponent {
    private changeSub: Subscription;
    private unscreenableOutput: UnscreenableModel;
    private screenableSelected: boolean = false;
    private unscreenableSelected: boolean = false;
    public screenableCriteria: TemplateCriteriaModel[];
    public nonScreenableCriteria: TemplateCriteriaModel[];

    public criteriaLevel3Id: string;
    public edit: string;
    public targetType: typeof TargetType = TargetType;
    public type: TargetType
    public selectDisabled: boolean = true;
    public name: string;
    public shortName: string;

    //screenable components
    @ViewChildren(BaseCriteriaTemplateComponent) screenableComps: QueryList<ICriteriaTemplate>;

    constructor(
        @Host() private rootComponent: AppComponent,
        @Host() private criteriaComponent: CriteriaComponent,
        private route: ActivatedRoute,
        private toolsService: ReportingService) {
    }

    ngOnInit() {
        this.route.parent.params.subscribe(param => {
            this.type = param['type'];            
            this.route.params.subscribe(param => {
                this.edit = param['edit'];
                this.name = param['name'];
                this.shortName = param['shortName'];
                this.criteriaLevel3Id = param['lvl3'];
                this.toolsService.getTemplateCriteria(null, null, this.criteriaLevel3Id).subscribe(criteria => {
                    let screenable = criteria.filter(x => x.isScreenable == true);
                    if (this.type == this.targetType.Report)
                        this.nonScreenableCriteria = criteria;
                    else {
                        this.nonScreenableCriteria = [];
                        this.screenableCriteria = screenable;
                        this.nonScreenableCriteria = this.nonScreenableCriteria.concat(criteria.filter(x => x.isScreenable != true));
                    }
                    
                    this.rootComponent.finishLoading();
                });
            });
        });

        this.changeSub = BaseCriteriaTemplateComponent.changed.subscribe(enable => {
            this.screenableSelected = enable;
            this.selectDisabled = !enable && !this.unscreenableSelected;
        })
    }

    ngOnDestroy() {
        this.changeSub.unsubscribe();
    }

    public toggleCheck(e: any, criteria: TemplateCriteriaModel) {
        criteria.isOn = e.target.checked;
        if (criteria.isOn) {
            this.selectDisabled = false;
            this.unscreenableSelected = true;
            criteria.isDataPoint = true;
            if (this.unscreenableOutput == undefined)
                this.unscreenableOutput = new UnscreenableModel(criteria.name, criteria.criteriaLevel2, criteria.id, criteria.criteriaType, []);

            if (this.unscreenableOutput)
                this.unscreenableOutput.isNotScreenableCriteriaItems.push(criteria);

            //criteria type 4 must also send the claimSymbol if we do not have screenable items
            if (this.unscreenableOutput.type == 4)
                this.unscreenableOutput.claimSymbol = criteria.criteriaEntityField.split(' ')[0];
        }
        else {
            this.unscreenableOutput.isNotScreenableCriteriaItems.splice(
                this.unscreenableOutput.isNotScreenableCriteriaItems.findIndex(x => x.id == criteria.id), 1);

            this.unscreenableSelected = this.unscreenableOutput.isNotScreenableCriteriaItems.length != 0;
            this.selectDisabled = !this.screenableSelected && !this.unscreenableSelected;

            this.criteriaComponent.updateCriteriaSummary();
        }
    }


    public addCriteria() {
        let screenableOutput: BaseTemplateOutput;
        let criteriaOutput: ICriteriaOutput;
        let unscreenableItems: TemplateCriteriaModel[] = this.unscreenableOutput ? this.unscreenableOutput.isNotScreenableCriteriaItems : [];
        //browse screenable and get updated values
        this.screenableComps.forEach(criteria => {
            criteriaOutput = criteria.save();
            switch (criteria.type) {
                case TemplateType.Slider:
                    screenableOutput = new SliderModel(
                        criteria.templateCriteria.criteriaLevel2,
                        this.criteriaLevel3Id,
                        criteria.templateCriteria.criteriaType,
                        [criteriaOutput as SliderOutput],
                        unscreenableItems);
                    break;
                case TemplateType.Histogram:
                    screenableOutput = new HistogramModel(
                        criteria.templateCriteria.criteriaLevel2,
                        this.criteriaLevel3Id,
                        criteria.templateCriteria.id,
                        criteria.templateCriteria.name,
                        criteria.templateCriteria.criteriaType,
                        unscreenableItems,
                        (criteriaOutput as HistogramOutput).minValue,
                        (criteriaOutput as HistogramOutput).maxValue);
                    break;
                case TemplateType.Multiselect:
                    screenableOutput = new MultiSelectModel(
                        criteria.templateCriteria.criteriaLevel2,
                        this.criteriaLevel3Id,
                        criteria.templateCriteria.id,
                        criteria.templateCriteria.name,
                        criteria.templateCriteria.criteriaType,
                        unscreenableItems,
                        [criteriaOutput as MultiselectOutput]);
                    break;
                case TemplateType.Involvement:
                    screenableOutput = new InvolvementModel(
                        criteria.templateCriteria.criteriaLevel2,
                        this.criteriaLevel3Id,
                        criteria.templateCriteria.id,
                        criteria.templateCriteria.name,
                        criteria.templateCriteria.criteriaType,
                        null,
                        unscreenableItems,
                        (criteriaOutput as InvolvementOutput).selectedCategories,
                        (criteriaOutput as InvolvementOutput).symbol);
                    break;
            };
        });
        //if we do not have screenable criteria selected, send unscreenable criteria changes
        this.criteriaComponent.criteriaChanged.emit(screenableOutput ? [screenableOutput] : [this.unscreenableOutput]);
    }

    public checkStatus(criteriaId: string): boolean {
        return this.unscreenableOutput &&
            this.unscreenableOutput.isNotScreenableCriteriaItems.findIndex(x => x.id == criteriaId) > -1;
    }
}

